package com.gin.no_gay_alliance.activity;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Message;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import com.gin.jackson.utils.ObjectUtils;
import com.gin.nga.enums.PrivateMessageStatus;
import com.gin.nga.method.NukeApi;
import com.gin.nga.params.nuke.pm.PmKickParam;
import com.gin.nga.params.nuke.pm.PmReplyParam;
import com.gin.nga.response.body.BaseMessageBody;
import com.gin.nga.response.body.nuke.PmReplyBody;
import com.gin.nga.response.field.SimpleUserInfo;
import com.gin.nga.response.field.pm.PrivateMessageReply;
import com.gin.nga.response.field.user.UserInfoContext;
import com.gin.no_gay_alliance.R;
import com.gin.no_gay_alliance.adpter.user.UserLinkAdapter;
import com.gin.no_gay_alliance.app.MyApplication;
import com.gin.no_gay_alliance.callback.Callback;
import com.gin.no_gay_alliance.callback.MsgCallback;
import com.gin.no_gay_alliance.callback.RequestCallback;
import com.gin.no_gay_alliance.databinding.ActivityPriMsgReadBinding;
import com.gin.no_gay_alliance.databinding.DialogPriMsgReplyBinding;
import com.gin.no_gay_alliance.exception.RequireParamException;
import com.gin.no_gay_alliance.fragment.primsg.PriMsgPageFragment;
import com.gin.no_gay_alliance.itemdecoration.SimpleItemDecoration;
import com.gin.no_gay_alliance.utils.AlertDialogUtils;
import com.gin.no_gay_alliance.utils.HandlerMessage;
import com.gin.no_gay_alliance.utils.InputMethodManagerUtils;
import com.gin.no_gay_alliance.utils.PopupMenuUtils;
import com.gin.no_gay_alliance.utils.ViewUtils;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 读私信
 *
 * @author : ginstone
 * @version : v1.0.0
 * @since : 2023/9/1 14:25
 **/
public class PriMsgReadActivity extends BaseBindingActivity<ActivityPriMsgReadBinding> implements TabLayoutMediator.TabConfigurationStrategy, Callback<BaseMessageBody> {

    public static final String ARG_ID = "id";
    public static final String ARG_COUNT = "count";
    public static final String ARG_FROM_SYSTEM = "from_system";
    private long id;
    private int totalPage;
    private boolean fromSystem;
    /**
     * 总回复数,仅供参考
     */
    private int count;
    private TabLayoutMediator tabLayoutMediator;
    private UserLinkAdapter adapter;
    /**
     * 发起人用户id
     */
    private long starterUid;

    /**
     * 解析意图
     *
     * @param intent 意图
     */
    @Override
    protected void handleIntent(Intent intent) {
        id = intent.getLongExtra(ARG_ID, -1);
        count = intent.getIntExtra(ARG_COUNT, -1);
        fromSystem = intent.getBooleanExtra(ARG_FROM_SYSTEM, false);
        if (id == -1) {
            throw new RequireParamException();
        }
        totalPage = 1;

        // 计算最大页
        if (count > 0) {
            totalPage = (count - 1) / 20 + 1;
        }
    }

    /**
     * onCreate中的后续操作
     */
    @Override
    protected void onCreate() {
        b.vp2.setAdapter(new FragmentStateAdapter(this) {
            @NonNull
            @Override
            public Fragment createFragment(int position) {
                return PriMsgPageFragment.newInstance(new PriMsgPageFragment.Args(id, position + 1));
            }

            @Override
            public int getItemCount() {
                return totalPage;
            }
        });

        tabLayoutMediator = attachTabLayout(tabLayoutMediator, b.tabLayout, b.vp2);

        adapter = new UserLinkAdapter(this, new ArrayList<>()) {
            @Override
            public boolean onLongClick(View v) {
                if (v.getTag() instanceof UserInfo) {
                    UserInfo user = (UserInfo) v.getTag();
                    // 移除用户
                    //如果自己是发起人，弹出菜单
                    if (MyApplication.getClient().getUserId() == starterUid) {
                        PopupMenuUtils.create(PriMsgReadActivity.this, v, R.menu.pri_msg_user, item -> {
                            // 踢出
                            if (item.getItemId() == R.id.menu_item_pri_msg_kick) {
                                kick(user);
                            }
                            // 拉黑
                            if (item.getItemId() == R.id.menu_item_pri_msg_block) {
                                block(user);
                            }
                            return true;
                        }).show();
                    } else {
                        // 拉黑
                        block(user);
                    }

                    return true;
                }
                return super.onLongClick(v);
            }
        };
        b.recyclerView.setAdapter(adapter);
        b.recyclerView.addItemDecoration(new SimpleItemDecoration());
    }

    /**
     * 装载右上角菜单
     *
     * @param menu         菜单
     * @param menuInflater 菜单渲染器
     */
    @Override
    protected void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
        menuInflater.inflate(R.menu.pri_msg_menu, menu);
    }

    @Override
    public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
        tab.setText(String.valueOf(position + 1));
    }

    /**
     * 处理消息
     *
     * @param message 消息
     * @return 是否消耗该消息
     */
    @Override
    public boolean handleMessage(@NonNull Message message) {
        if (message.what == HandlerMessage.UPDATE_PRI_REPLY_BODY) {
            PmReplyBody.Data body = (PmReplyBody.Data) message.obj;
            fromSystem = body.getStatus().contains(PrivateMessageStatus.FROM_SYSTEM);

            PrivateMessageReply firstReply = body.getData().get(0);
            starterUid = body.getStarterUid() != null ? body.getStarterUid() : 0;


            // 根据响应得到的最大页数
            int page = body.getPage() + hasNext(body.getHasNext());
            // 更新最大页数
            this.totalPage = Math.max(this.totalPage, page);

            // 参与用户
            List<SimpleUserInfo> users = body.getUsers();
            // 参与用户的相关views
            View[] userViews = {b.tvUsers, b.recyclerView, b.divider};
            if (!ObjectUtils.isEmpty(users)) {
                List<UserLinkAdapter.UserInfo> data = users.stream().filter(i -> i.getUserId() != 0 && !ObjectUtils.isEmpty(i.getUsername())).map(UserLinkAdapter.UserInfo::new).peek(item -> {
                    Object userInfo = body.getUserContext().getUserInfo(item.userId, null);
                    if (userInfo instanceof UserInfoContext) {
                        UserInfoContext info = (UserInfoContext) userInfo;
                        item.avatar = info.getAvatar();
                        item.username = info.getUserInfo().getUsername();
                    }
                }).collect(Collectors.toList());
                adapter.updateData(data);
                ViewUtils.setGone(data.isEmpty(), userViews);
            } else {
                ViewUtils.setVisibility(View.GONE, userViews);
            }
        }

        return super.handleMessage(message);
    }

    /**
     * 如果布局中直接有toolbar, 在此提供, 如果使用Fragment布局中的toolbar,Fragment渲染完成后调用 setToolbar 方法装载
     *
     * @return toolbar toolbar
     */
    @Override
    protected Toolbar initToolbar() {
        return b.toolbar;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        MenuItem item = menu.findItem(R.id.menu_item_pri_msg_reply);
        if (item != null) {
            item.setVisible(!fromSystem);
        }
        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        // 退出会话
        if (item.getItemId() == R.id.menu_item_pri_msg_quit) {
            AlertDialogUtils.showConfirm(this, "离开会话", "确认退出当前会话？本操作不可逆", (dialog, which) -> {
                if (which == DialogInterface.BUTTON_POSITIVE) {
                    PmKickParam param = new PmKickParam(id, MyApplication.getClient().getUserId());
                    NukeApi.pmKick(MyApplication.getClient(), param).async(new RequestCallback<>(d -> {
                        toast(d.getMessage());
                        finish();
                    }));
                }
            });
            return true;
        }
        // 回复私信
        if (item.getItemId() == R.id.menu_item_pri_msg_reply) {
            if (fromSystem) {
                toast("系统消息禁止回复");
                return true;
            }
            DialogPriMsgReplyBinding bb = DialogPriMsgReplyBinding.inflate(getLayoutInflater());

            AlertDialogUtils.showConfirm(this, "回复私信", null, bb.getRoot(), (dialog, which) -> {
                if (which == DialogInterface.BUTTON_POSITIVE) {
                    // 发送回复
                    String title = bb.etTitle.getText().toString();
                    String content = bb.etContent.getText().toString();
                    if (ObjectUtils.isEmpty(content)) {
                        toast("正文不能为空");
                        return;
                    }
                    PmReplyParam param = new PmReplyParam(id, title, content);
                    NukeApi.pmReply(MyApplication.getClient(), param).async(new MsgCallback(handler) {
                        @Override
                        public void onSuccess(BaseMessageBody body) {
                            super.onSuccess(body);
                            // 刷新
                            Fragment fragment = getSupportFragmentManager().findFragmentByTag("f" + b.vp2.getCurrentItem());
                            if (fragment instanceof PriMsgPageFragment) {
                                ui(() -> ((PriMsgPageFragment) fragment).sendRequest());
                            }
                        }
                    });
                }
            });

            bb.etContent.requestFocus();
            InputMethodManagerUtils.show(handler, bb.etContent);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * 请求成功回调
     *
     * @param data 数据
     */
    @Override
    public void onSuccess(BaseMessageBody data) {
        toast(data.getMessage());
    }

    /**
     * 拉黑用户
     *
     * @param user 用户
     */
    private void block(UserLinkAdapter.UserInfo user) {
        AlertDialogUtils.showConfirm(this, "私信拉黑", String.format("确认将 %s 私信拉黑？", user.username), (dialog, which) -> {
            if (which == DialogInterface.BUTTON_POSITIVE) {
                NukeApi.pmBlockAdd(MyApplication.getClient(), user.userId).async(new RequestCallback<>(this));
            }
        });
    }

    /**
     * 踢出用户
     *
     * @param user 用户
     */
    private void kick(UserLinkAdapter.UserInfo user) {
        AlertDialogUtils.showConfirm(this, "踢出用户", String.format("确认将 %s 移出当前会话？", user.username), (dialog, which) -> {
            if (which == DialogInterface.BUTTON_POSITIVE) {
                PmKickParam param = new PmKickParam(id, user.userId);
                NukeApi.pmKick(MyApplication.getClient(), param).async(new RequestCallback<>(this));
            }
        });
    }

    /**
     * 启动活动
     *
     * @param context    上下文
     * @param id         id
     * @param count      回复数(预设,用来计算总页数)
     * @param fromSystem 是否为系统消息
     */
    public static void startActivity(Context context, long id, int count, boolean fromSystem) {
        Intent intent = new Intent(context, PriMsgReadActivity.class);
        intent.putExtra(ARG_ID, id);
        intent.putExtra(ARG_COUNT, count);
        intent.putExtra(ARG_FROM_SYSTEM, fromSystem);
        context.startActivity(intent);
    }

    private static int hasNext(String hasNext) {
        if ("true".equals(hasNext) || "1".equals(hasNext)) {
            return 1;
        }
        return 0;
    }
}
